#!/bin/sh
# script based on initial implementation
# by Vitaly Gusach (http://gusach.org.ua)
#
# purpose: warn on those entries in given packagelists(s)
# which are definitely absent; the build might still bail out
# but at least 80% of failures can be predicted early now
#
# usage: check-pkg-list [-n pkgnames] [--aptbox $PATH/to/aptbox] pkglist ...
# (pkgnames file should contain `apt-cache pkgnames`)
# NB: -n pkgnames MUST go first, if given

RET_ERROR=

error() {
	echo `basename $0`: $* >&2
	exit 1
}

exit_handler() {
	local rc=$?
	trap - EXIT
	rm -f -- "$ftemp" "$fpkgnames" "$fpkgwildcards" "$favaillist" "$fpkgerrors"
	exit $rc
}

# figure out apt.conf from recent aptbox or fallback to system one
dump_pkgnames() {
	${APTBOX:+$APTBOX/}apt-cache pkgnames  | sort -u > "$favaillist"
}

check_pkglist() {
	fprofilelist="$1"
	[ -f "$fprofilelist" ] || error "invalid packagelist filename: $fprofilelist"
	# cleaning pkg list from comments, empty lines,
	# splitting several pkgnames on the same line
	sed -e '/^#/d' -e '/^[ 	]*$/d' -e 's/ \+$//' -e 's/[ 	]\+/\n/g' \
	< "$fprofilelist" \
	| sed 's/-$//' \
	| sort -u \
	> "$ftemp" # got list of pkgnames we need

	# split pkgnames without wildcards and with wildcards
	grep -F -v '*' "$ftemp" > "$fpkgnames"
	grep -F    '*' "$ftemp" > "$fpkgwildcards"

	# return unavailable packages
	comm -23 "$fpkgnames" "$favaillist" > "$fpkgerrors"

	# return unavailable wildcards
	while read i; do
		# replacing * with regexp's \.+
		pattern="^`echo ${i#^} | sed -e 's/\*/.\\\\+/'`$"
		grep -q "$pattern" "$favaillist" || echo "$i" >> "$fpkgerrors"
	done < "$fpkgwildcards"
	if [ -s "$fpkgerrors" ]; then
		echo "** error: Packages are not available in $fprofilelist:" >&2
		RET_ERROR=1
		cat $fpkgerrors >&2
	fi
}

[ "$#" -gt 0 ] || error "need at least one argument, a packagelist to check"

# reusable temporary files with self-cleanup at exit
TEMP="${TMP:-/tmp}"
trap exit_handler HUP INT QUIT TERM EXIT
favaillist="`mktemp $TEMP/pkgchecker.avail.XXXXX`"
fpkgnames="`mktemp $TEMP/pkgchecker.names.XXXXX`"
fpkgwildcards="`mktemp $TEMP/pkgchecker.wildcards.XXXXX`"
fpkgerrors="`mktemp $TEMP/pkgchecker.error.XXXXX`"
ftemp="`mktemp $TEMP/pkgchecker.XXXXX`"

# check args
while :; do
	case "$1" in
	# make sure pkgnames dump is handy
	"-n"|"--pkgnames")
		[ -f "$2" ] && {
			sort "$2" > "$favaillist"
			shift; shift
		} || error "-n needs valid pkgnames filename"
		;;
	# PATH to aptbox
	"--aptbox")
		[ -d "$2" ] && {
			APTBOX="$2"
			shift; shift
		} || error "--aptbox needs valid directory"
		;;
	*)
		break
		;;
	esac
done

[ -s "$favaillist" ] || dump_pkgnames

for list in "$@"; do
	check_pkglist "$list"
done

[ -z "$RET_ERROR" ] || error "Some lists contain unavailable packages"
